<?php

namespace control;
/*
*内部转账类
*/

class innerTransferClass extends adIndexClass
{
    private const page = 'innerTransfer';
    private const table = 'account_inner';
    private const title = '内部转账';


    /**
     * 生成凭证
     * @return bool|string
     */
    public function voucherEdit(): bool|string
    {
        $listId      = $this->post('listId');
        $listArr     = explode(',', $listId);
        $voucherWord = query('voucher_word', "coid = '" . self::$coid . "' and word = '记'");


        $json['warn'] = '';
        $suc          = 0;
        $text         = '';
        foreach ($listArr as $bookkeepingId) {
            $account_inner = query(self::table, "id = '$bookkeepingId'");
            if (empty($account_inner['voucherId'])) {
                $voucherNo = voucherEditClass::voucherNo($voucherWord['id'], $account_inner['recordDate']);;
                $field      = [
                    'recordDate'    => $account_inner['recordDate'],
                    'voucherWordId' => $voucherWord['id'],
                    'voucherNo'     => $voucherNo,
                    'text'          => $this->post('text'),
                ];
                $annotation = [
                    'recordDate'    => '日期',
                    'voucherWordId' => '凭证字',
                    'voucherNo'     => '凭证号',
                ];
                $rules      = [
                    'recordDate'    => 'required',
                    'voucherWordId' => 'required',
                    'voucherNo'     => 'required|unsigned_int',
                ];
                // 校验是否符合规则
                $vt     = new \verify();
                $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
                if ($result === false) {
                    $text .= "日期【{$account_inner['recordDate']}】,ID【$account_inner[id]】的数据" . $vt->getErrs()[0] . "<br>";  // 多个规则提示最前面一条
                } elseif (checkoutClass::isChecked($field['recordDate'])) {
                    $text .= "日期【{$account_inner['recordDate']}】,ID【$account_inner[id]】的数据所处期间已结账<br>";
                } else {
                    $this->startTrans();
                    $company = query('company', "coid = '" . self::$coid . "'");
                    if ($company['isAudit']) {
                        $field['workFlow'] = '待审核';
                    } else {
                        $field['workFlow'] = '已记账';
                    }
                    $field        = array_merge($field, [
                        'id'         => suiji(),
                        'coid'       => self::$coid,
                        'isTemplate' => '否',
                        'source'     => '正常',
                        'stid'       => self::$stid,
                        'money'      => self::yuanToCent($account_inner['money'])
                    ]);
                    $json['warn'] = static::insert(["table" => 'voucher', "field" => $field]);
                    $outAccount   = query('account', "id = '$account_inner[outAccountId]'");
                    //账户科目
                    $outAccountSubject = query('subject', "id = '$outAccount[subjectId]'");

                    $inAccount        = query('account', "id = '$account_inner[inAccountId]'");
                    $inAccountSubject = query('subject', "id = '$inAccount[subjectId]'");

                    if (empty($inAccountSubject['id'])) {
                        $json['warn'] = "账户未绑定科目，请前往账户绑定科目";
                        $text         .= "日期【{$account_inner['recordDate']}】,ID【$account_inner[id]】的数据账户未绑定科目，请前往账户绑定科目<br>";
                    } elseif (empty($outAccountSubject['id'])) {
                        $json['warn'] = "未进行凭证设置";
                        $text         .= "日期【{$account_inner['recordDate']}】,ID【$account_inner[id]】的数据未进行凭证设置<br>";
                    } else {
                        $collection = [
                            'voucherPrice' => 0,
                            'voucherRate'  => 0,
                            'voucherMoney' => 0,
                        ];
                        $warn       = static::insert(array(
                            'table' => 'voucher_detail',
                            'field' => [
                                'id'           => suiji(),
                                'coid'         => self::$coid,
                                'orderId'      => $field['id'],
                                'summary'      => $account_inner['summary'],
                                'subjectId'    => $inAccountSubject['id'],
                                'subjectName'  => $inAccountSubject['name'],
                                'subjectCode'  => $inAccountSubject['code'],
                                'direction'    => $inAccountSubject['direction'],
                                'money'        => self::yuanToCent($account_inner['money']),
                                'subjectAttr'  => json_encode($collection, 320),
                                'khid'         => '',
                                'supplierId'   => '',
                                'staffId'      => '',
                                'projectId'    => '',
                                'materialId'   => '',
                                'cashId'       => '',
                                'departmentId' => '',
                                'voucherNum'   => 0,
                                'currencyId'   => '',
                                'unit'         => '',

                            ]
                        ));
                        if (!in_array($warn, ["新增成功", "更新成功"])) {
                            $json['warn'] = $warn;
                            break;
                        }
                        $collection = [
                            'voucherPrice' => 0,
                            'voucherRate'  => 0,
                            'voucherMoney' => 0,
                        ];
                        $warn       = static::insert(array(
                            'table' => 'voucher_detail',
                            'field' => [
                                'id'           => suiji(),
                                'coid'         => self::$coid,
                                'orderId'      => $field['id'],
                                'summary'      => $account_inner['summary'],
                                'subjectId'    => $outAccountSubject['id'],
                                'subjectName'  => $outAccountSubject['name'],
                                'subjectCode'  => $outAccountSubject['code'],
                                'direction'    => $inAccountSubject['direction'] == '借' ? '贷' : '借',
                                'money'        => self::yuanToCent($account_inner['money']),
                                'subjectAttr'  => json_encode($collection, 320),
                                'khid'         => '',
                                'supplierId'   => '',
                                'staffId'      => '',
                                'projectId'    => '',
                                'materialId'   => '',
                                'cashId'       => '',
                                'departmentId' => '',
                                'voucherNum'   => 0,
                                'currencyId'   => '',
                                'unit'         => '',
                            ]
                        ));
                        if (!in_array($warn, ["新增成功", "更新成功"])) {
                            $json['warn'] = $warn;
                            $text         .= "日期【{$account_inner['recordDate']}】,ID【$account_inner[id]】的数据生成凭证明细失败<br>";
                        }
                    }
                    $warn = update(array('table' => self::table, 'field' => ['voucherId' => $field['id']], 'where' => "id = '$account_inner[id]'"));
                    if ($warn != '更新成功') {
                        $json['warn'] = $warn;
                        break;
                    }
                    if ($warn != '更新成功') {
                        $json['warn'] = $warn;
                        $text         .= "日期【{$account_inner['recordDate']}】,ID【$account_inner[id]】的数据更新凭证ID失败<br>";
                    }
                    if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                        $suc++;
                        $this->commitTrans();
                        $text .= "日期【{$account_inner['recordDate']}】,ID【$account_inner[id]】的数据生成凭证成功<br>";
                    } else {
                        $this->rollback();
                        $text .= "日期【{$account_inner['recordDate']}】,ID【$account_inner[id]】的数据生成凭证失败：编辑失败<br>";
                    }
                }
            }
        }
        $this->logText(["type" => self::page, "text" => $text]);
        $json['warn']     = 2;
        $json['href']     = root . "control/adIndex.html?cla=" . self::page . "&fun=home";
        $_SESSION['warn'] = "成功生成了{$suc}个凭证";
        return json_encode($json, 320);
    }

    /**
     * 生成凭证页面
     */
    public function generateVoucher(): string
    {
        $listId      = $this->get('listId');
        $listArr     = explode(',', $listId);
        $lefItem     = '';
        $rightItem   = '';
        $voucherWord = query('voucher_word', "coid = '" . self::$coid . "' and word = '记'");
        $index       = 0;
        foreach ($listArr as $bookkeepingId) {
            $account_inner = query(self::table, "id = '$bookkeepingId'");
            if (empty($account_inner['voucherId'])) {
                $index++;//序号
                $recordMonth                                    = date('Y-m', strtotime($account_inner['recordDate']));
                $voucherIndex[$voucherWord['id']][$recordMonth] = $voucherIndex[$voucherWord['id']][$recordMonth] ?? 1;
                $outAccount                                     = query('account', "id = '$account_inner[outAccountId]'");
                //账户科目
                $outAccountSubject = query('subject', "id = '$outAccount[subjectId]'");

                $inAccount        = query('account', "id = '$account_inner[inAccountId]'");
                $inAccountSubject = query('subject', "id = '$inAccount[subjectId]'");
                $lefItem          .= <<<eof
                        <div class="left-box-item">
                            <div class="item-li-no">内部转账：$index</div>
                            <div class="item-li-content">
                                <div>日期：{$account_inner['recordDate']}</div>
                                <div>摘要：{$account_inner['summary']}</div>
                                <div>转入账户：{$inAccount['orderNo']}-{$inAccount['name']}</div>
                                <div>转出账户：{$outAccount['orderNo']}-{$outAccount['name']}</div>
                            </div>
                        </div>
eof;

                $bigMoney = voucherEditClass::num_to_rmb($account_inner['money']);
                $money    = $account_inner['money'];
                $jieMoney = $daiMoney = 0;
                if ($outAccountSubject['direction'] == '借') {
                    $jieMoney = $money;
                    $daiMoney = '';
                } elseif ($outAccountSubject['direction'] == '贷') {
                    $jieMoney = '';
                    $daiMoney = $money;
                }

                $voucherNo                                      = voucherEditClass::voucherNo($voucherWord['id'], $account_inner['recordDate'], $voucherIndex[$voucherWord['id']][$recordMonth]);
                $voucherIndex[$voucherWord['id']][$recordMonth] += 1;
                $rightItem                                      .= <<<eof
                        <div class="right-box-item">
                            <div class="item-li-no"><span>日期：{$account_inner['recordDate']}</span> <span style="margin-left: 20px">凭证字号：记-{$voucherNo}</span> <span style="margin-left: 20px">附件：0</span></div>
                            <div class="item-li-content right-item">
                                <div class="voucher-line">
                                    <div class="voucher-line-summary">{$account_inner['summary']}</div>
                                    <div class="voucher-line-subject">{$inAccountSubject['code']} {$inAccountSubject['name']}</div>
                                    <div class="voucher-line-jie">$jieMoney</div>
                                    <div class="voucher-line-dai">$daiMoney</div>
                                </div>
                                <div class="voucher-line">
                                    <div class="voucher-line-summary">{$account_inner['summary']}</div>
                                    <div class="voucher-line-subject">{$outAccountSubject['code']} {$outAccountSubject['name']}</div>
                                    <div class="voucher-line-jie">$daiMoney</div>
                                    <div class="voucher-line-dai">$jieMoney</div>
                                </div>
                                <div class="voucher-line">
                                    <div class="voucher-line-summary">合  计</div>
                                    <div class="voucher-line-subject">$bigMoney</div>
                                    <div class="voucher-line-jie">$money</div>
                                    <div class="voucher-line-dai">$money</div>
                                </div>
                            </div>
                        </div>
eof;
            }
        }
        $data['html'] = <<<efo
        <form name="voucherForm">
        <div class="voucher-body">
            <div class="voucher-title">内部转账</div>
            <div class="calendarBody">
                <div class="voucher-button"><span class="spanButton li-btn-blue-bg" style="margin-left: 0" onclick="subForm('voucherForm',root+'control/adIndex.html?cla=innerTransfer&fun=voucherEdit')">保存</span><span class="spanButton" onclick="newIframe('内部转账',root+'control/adIndex.html?cla=innerTransfer&fun=home')">取消</span></div>
                <div class="input-div bold">
                    <div>日记账</div>
                    <div>凭证预览</div>
                </div>
                <div class="content-box">
                    <div class="left-content-box">
                        $lefItem
                    </div>
                    <div class="right-content-box">
                        $rightItem
                    </div>
                </div>
            </div>
        </div>
        <input name="listId" type="hidden" value="$listId">
        </form>
efo;
        $bankObj      = new bankBookClass();
        $data['html'] .= $bankObj->voucherCass();
        //返回
        return $this->tab($data);
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "摘要" => text(array("name" => "summary")),
                    "备注"   => text(array("name" => "text")),
                    '日期' => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*列表-查询条件*/
    public function home()
    {
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        if ($this->power(self::page, "edit")) {
            $button .= "<span class='spanButton li-btn-blue-bg' onclick='voucher()'>生成凭证</span>\n";
        }
        if ($this->power(self::page, 'import')) {
            $button .="<span class='spanButton' onclick=\"layer('importTemplate','importFrame',{cla:'".self::page."'})\">导入</span>";
        }
        if ($this->power(self::page, "export")) {
            $button .= "  <a href='" . root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=exportData'><span class='spanButton'>导出</span></a>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">删除</span>\n";
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'recordDate'    => [
                        'name'  => "日期",
                        'width' => 150,
                        'sort'  => 1,
                    ],
                    'summary'       => [
                        'name'  => '摘要',
                        'width' => 300,
                    ],
                    'accountOut'    => [
                        'name'  => '转出账户',
                        'width' => 300,
                    ],
                    'accountIn'     => [
                        'name'  => '转入账户',
                        'width' => 300,
                    ],
                    'text'          => [
                        'name'  => '备注',
                        'width' => 200,
                    ],
                    'money'         => [
                        'name'  => '金额',
                        'width' => 150,
                        'sort'  => 1,
                    ],
                    'voucherButton' => [
                        'name'  => '关联凭证',
                        'width' => 150,
                    ]
                ];
        }
        return $tr;
    }

    /*客户列表-查询结果*/
    public function homeSearch()
    {
        //like查询数组
        $like = array(
            "summary" => $this->post('summary'),
            "text"    => $this->post('text'),
        );
        //全等查询数组
        $equal = array(
            "coid" => self::$coid,
        );
        $and   = "";
        if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'), field: 'recordDate');
        }
        //排序
        $orderBy = $this->listSort(array(
            "search" => $this->post('list_sort_key') ?: 'recordDate desc,list',
            "sort"   => $this->post('list_sort') ?: "desc",
            "array"  => array(),
        ));
        //获取查询结果
        $where = search(array("like" => $like, "=" => $equal)) . $and;
        $page  = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        static::rSet(self::$stid . self::page . 'sql', $page['fullSql']);
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //第一行，特殊处理
        $first = array(
            'recordDate'    => text(array('name' => 'recordDate', 'class' => 'text width100', 'value' => $this->date, 'laydate' => ['done' => "function(e){ $('[name=recordDate]').val(e);insertOne($('[name=recordDate]'))}"])),
            'summary'       => text(array('name' => 'summary', 'id' => 'summary', 'class' => 'text', 'blur' => 'insertOne')),
            'accountOut'    => text(array('name' => 'accountOut', 'class' => 'text width200', 'id' => 'accountOut')) . hidden(array('name' => 'outAccountId', 'value' => '')),
            'accountIn'     => text(array('name' => 'accountIn', 'class' => 'text width200', 'id' => 'accountIn')) . hidden(array('name' => 'inAccountId', 'value' => '')),
            'text'          => text(array('name' => 'text', 'class' => 'text width150')),
            'money'         => text(array('name' => 'money', 'blur' => 'insertOne', 'class' => 'text width100', 'type' => 'number')),
            'voucherButton' => ''
        );
        $liButton[] = "";
        //本行初始化
        $row = [];
        foreach ($installSearch['key'] as $key) {
            switch ($key) {
                default:
                    $row[] = isset($first[$key]) && $first[$key] ? $first[$key] : '';
            }
        }
        $body[] = $row;
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate      = array(
                "box"  => array("name" => "listId", "value" => $array['id']),
                "edit" => array("title" => "编辑", "click" => "layer('" . self::page . "','edit',{id:'" . $array['id'] . "'})"),
            );
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'accountOut':
                        $accountOut    = query('account', "id = '$array[outAccountId]'");
                        $row[]   = $accountOut['orderNo'] . $accountOut['name'];
                        break;
                    case 'accountOu':
                        $accountIn     = query('account', "id = '$array[inAccountId]'");
                        $row[]   = $accountIn['orderNo'] . $accountIn['name'];
                        break;
                    case 'voucherButton':
                        $voucher       = query('voucher', "id = '$array[voucherId]'");
                        $voucherWord   = query('voucher_word', "id = '$voucher[voucherWordId]'");
                        $voucherButton = '';
                        if (!empty($voucher['id'])) {
                            unset($dominate['edit']);
                            $voucherButton = componentClass::urlTitle($voucherWord['word'] . '-' . $voucher['voucherNo'], root . 'control/adIndex.html?cla=voucherEdit&fun=home&id=' . $array['voucherId'], '录凭证');
                        }
                        $row[] = $voucherButton;
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $button = "";
        //合计金额
        $money     = find(array('table' => self::table, 'single' => $where, 'field' => "ifnull(sum(money),0) as money"))['money'];
        $total    = [
            'money'   => $money,
        ];
        //生成页面
        $li = $this->li(array(
            "body"        => $body,
            "install"     => $installSearch,
            "button"      => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page"        => $page['para'],
            "total"       => $total,
        ));
        //返回
        $json['html'] =
            $page['hint'] .
            $button .
            "<form name='listForm'>" .
            hidden(array('name' => 'accountId', 'value' => $this->post('accountId'))) .
            $li .
            "</form>" .
            $this->js() .
            $page['button'] .
            clear;
        return json_encode($json, 320);
    }

    /**
     * 编辑
     * @return false|string
     */
    public function edit()
    {
        $info = query(self::table, "id = '" . $this->post('id') . "'");
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                must . "日期：" => text(array("name" => "recordDate", 'laydate' => [], "value" => $info['recordDate']))
            ),
            array(
                must . "摘要：" => text(array("name" => "summary", "value" => $info['summary']))
            ),
            array(
                must . "转出账户：" => selectMultiple(array('name' => 'outAccountId', 'title' => '请选择', 'table' => 'account', 'sqlId' => 'id', 'field' => "concat(orderNo,name) as name,id", 'sqlField' => 'name', 'where' => "coid = '" . self::$coid . "' ", 'value' => $info['outAccountId']))
            ),
            array(
                must . "转入账户：" => selectMultiple(array('name' => 'inAccountId', 'title' => '请选择', 'table' => 'account', 'sqlId' => 'id', 'field' => "concat(orderNo,name) as name,id", 'sqlField' => 'name', 'where' => "coid = '" . self::$coid . "' ", 'value' => $info['inAccountId']))
            ),
            array(
                must . "金额：" => text(array("name" => "money", 'type' => 'number', "value" => $info['money']))
            ),
            array(
                "备注：" => text(array("name" => "text", "value" => $info['text']))
            ),
        )
        ));
        //返回
        return $this->layer(array("title" => "编辑", "height" => 550, "width" => 800, "html" => $html));
    }

    /**
     * JS
     * @return string
     */
    private function js()
    {
        return <<<eof
<script>
function voucher(){
    let arr = [];
    $("[name='listForm'] input[type=checkbox]:checked").each(function () {
        if ($(this).val() && $(this).val() !== 'on') {
            arr.push($(this).val());
        }
    });
    if (arr.length > 0) {
        let vals = arr.join(",");
        newIframe('内部转账',root+'control/adIndex.html?cla=innerTransfer&fun=generateVoucher&listId='+vals)
    } else {
        msg('请选择需要数据','error');
    }
}
$("#summary").bigAutocomplete({
    url:root + 'control/adIndex.html?cla=innerTransfer&fun=getSummary',
    callback:function(data,e){
}}) 
$("#accountOut").bigAutocomplete({
    url:root + 'control/adIndex.html?cla=innerTransfer&fun=getAccount',
    callback:function(data,e){
        $("[name='outAccountId']").val(data.id)
        insertOne(e)
}})
$("#accountIn").bigAutocomplete({
    url:root + 'control/adIndex.html?cla=innerTransfer&fun=getAccount',
    callback:function(data,e){
        $("[name='inAccountId']").val(data.id)
        insertOne(e)
}})
function insertOne(e){
    let money = $("[name='listForm'] [name='money']").val();
    let outAccountId = $("[name='listForm'] [name='outAccountId']").val();
    let inAccountId = $("[name='listForm'] [name='inAccountId']").val();
    let summary = $("[name='listForm'] [name='summary']").val();
    let recordDate = $("[name='listForm'] [name='recordDate']").val();
    if (summary && inAccountId && outAccountId && recordDate && money){
        subForm('listForm',root+'control/adIndex.html?cla=innerTransfer&fun=editEdit');
    }
}
</script>
eof;

    }

    public function getSummary(): bool|string
    {
        $val          = $this->post('keyword');//关键词
        $json['data'] = [];
        $where        = "coid='" . self::$coid . "'";
        if ($val) {
            $where .= " and summary like '%$val%'";
        }
        $res = find(array('table' => 'account_inner', 'field' => "distinct summary", 'where' => $where . " order by any_value(recordDate) desc,any_value(time) desc limit 40"));
        foreach ($res['array'] as $val) {
            $json['data'][] = array('title' => $val['summary']);
        }

        $json['warn'] = 2;
        return json_encode($json, 320);
    }

    /**
     * 模糊查询账户
     * @return bool|string
     */
    public function getAccount(): bool|string
    {
        $val          = $this->post('keyword');//关键词
        $json['warn'] = 0;
        $where        = empty($val) ? "and 1=1" : "and (name like '%" . $val . "%' or orderNo like '%" . $val . "%')";
        $all          = find(array('table' => 'account', 'where' => "coid = '" . self::$coid . "' $where order by time limit 50"));
        foreach ($all['array'] as $val) {
            $json['data'][] = array('title' => $val['orderNo'] . $val['name'], 'id' => $val['id']);
        }
        $json['warn'] = 2;
        return json_encode($json, 320);
    }

    public function editEdit()
    {
        $id         = $this->post('id') ?: self::getId();
        $field      = [
            'inAccountId'  => $this->post('inAccountId'),
            'outAccountId' => $this->post('outAccountId'),
            'recordDate'   => $this->post('recordDate'),
            'summary'      => $this->post('summary'),
            'money'        => $this->post('money'),
            'text'         => $this->post('text'),
        ];
        $annotation = [
            'outAccountId' => '转出账户',
            'inAccountId'  => '转入账户',
            'recordDate'   => '日期',
            'money'        => '金额',
            'summary'      => '摘要',
        ];
        $rules      = [
            'outAccountId' => 'required',
            'inAccountId'  => 'required',
            'recordDate'   => 'required|date',
            'money'        => 'required|numeric',
            'summary'      => 'required',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
            goto resp;
        }
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑" . self::title . "的权限";
        } elseif (checkoutClass::isChecked($field['recordDate'])) {
            $json['warn'] = '此日期处于已结账期间，不能编辑';
        } elseif ($field['inAccountId'] == $field['outAccountId']) {
            $json['warn'] = '转出账户和转入账户不能相同';
        } else {
            $this->startTrans();
            $where      = " id = '$id' ";
            $info       = query(self::table, $where);
            $inAccount  = query('account', "id = '$field[inAccountId]'");
            $outAccount = query('account', "id = '$field[outAccountId]'");
            if (!$info['id']) {
                $field        = array_merge($field, [
                    'id'   => $id,
                    'coid' => self::$coid,
                    'stid' => self::$stid,
                ]);
                $json['warn'] = static::insert(["table" => self::table, "field" => $field]);
                //添加日记账
                if ($inAccount['type'] == '现金') {
                    $userNo = codeTemplateClass::generateCode('cashBook', [
                        'prefix' => date('Ymd'),
                        'table'  => 'bookkeeping',
                        'field'  => 'orderNo',
                        'where'  => '',
                    ], []);
                } else {
                    $userNo = codeTemplateClass::generateCode('bankBook', [
                        'prefix' => date('Ymd'),
                        'table'  => 'bookkeeping',
                        'field'  => 'orderNo',
                        'where'  => '',
                    ], []);
                }
                $bool = static::insert(["table" => 'bookkeeping', "field" => [
                    'id'          => suiji(),
                    'orderNo'     => $userNo,
                    'type'        => $inAccount['type'] == '现金' ? '现金' : '银行账户',
                    'coid'        => self::$coid,
                    'stid'        => self::$stid,
                    'accountId'   => $field['inAccountId'],
                    'classify'    => '内部转账',
                    'recordDate'  => $field['recordDate'],
                    'summary'     => $field['summary'],
                    'income'      => $field['money'],
                    'sourceTable' => self::table,
                    'sourceId'    => $id,
                    'sign'        => '转入账户'
                ]]);
                if ($bool != '新增成功') {
                    $json['warn'] = $bool;
                }

                //添加日记账
                if ($outAccount['type'] == '现金') {
                    $userNo = codeTemplateClass::generateCode('cashBook', [
                        'prefix' => date('Ymd'),
                        'table'  => 'bookkeeping',
                        'field'  => 'orderNo',
                        'where'  => '',
                    ], []);
                } else {
                    $userNo = codeTemplateClass::generateCode('bankBook', [
                        'prefix' => date('Ymd'),
                        'table'  => 'bookkeeping',
                        'field'  => 'orderNo',
                        'where'  => '',
                    ], []);
                }
                $bool = static::insert(["table" => 'bookkeeping', "field" => [
                    'id'          => suiji(),
                    'orderNo'     => $userNo,
                    'type'        => $outAccount['type'] == '现金' ? '现金' : '银行账户',
                    'coid'        => self::$coid,
                    'stid'        => self::$stid,
                    'accountId'   => $field['outAccountId'],
                    'classify'    => '内部转账',
                    'recordDate'  => $field['recordDate'],
                    'summary'     => $field['summary'],
                    'expenses'    => $field['money'],
                    'sourceTable' => self::table,
                    'sourceId'    => $id,
                    'sign'        => '转出账户'
                ]]);
                if ($bool != '新增成功') {
                    $json['warn'] = $bool;
                }
            } else {
                $json['warn'] = static::update([
                    "table" => self::table,
                    "field" => $field,
                    "where" => $where
                ]);
                $bool         = static::update(["table" => 'bookkeeping', "field" => [
                    'type'       => $inAccount['type'] == '现金' ? '现金' : '银行账户',
                    'accountId'  => $field['inAccountId'],
                    'recordDate' => $field['recordDate'],
                    'summary'    => $field['summary'],
                    'income'     => $field['money'],
                ],
                                                'where' => "sourceId = '$info[id]' and sign = '转入账户'"
                ]);
                if ($bool != '更新成功') {
                    $json['warn'] = $bool;
                }

                $bool = static::update(["table" => 'bookkeeping', "field" => [
                    'type'       => $outAccount['type'] == '现金' ? '现金' : '银行账户',
                    'accountId'  => $field['outAccountId'],
                    'classify'   => '内部转账',
                    'recordDate' => $field['recordDate'],
                    'summary'    => $field['summary'],
                    'expenses'   => $field['money'],
                ], 'where'                      => "sourceId = '$info[id]' and sign = '转出账户'"]);
                if ($bool != '更新成功') {
                    $json['warn'] = $bool;
                }
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $this->commitTrans();
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
            } else {
                $this->rollback();
            }
        }

        resp:
        return json_encode($json, 320);
    }


    /**
     * 导出
     */
    public function exportData()
    {
        if (!$this->power(self::page, 'export')) {
            $_SESSION['warn'] = '你还没有导出的权限';
        } else {
            $data   = [];
            $sql    = static::rGet(self::$stid . self::page . 'sql');
            $title  = ["日期", "摘要", "转出账户", "转入账户", "备注", "金额", '凭证'];
            $result = self::sqlFind($sql);
            if (is_array($result)) {
                foreach ($result as $array) {
                    $accountOut  = query('account', "id = '$array[outAccountId]'");
                    $accountIn   = query('account', "id = '$array[inAccountId]'");
                    $voucher     = query('voucher', "id = '$array[voucherId]'");
                    $voucherWord = query('voucher_word', "id = '$voucher[voucherWordId]'");
                    $tr[]        = array($array['recordDate'], $array['summary'], $accountOut['orderNo'] . $accountOut['name'], $accountIn['orderNo'] . $accountIn['name'], $array['money'], $array['text'], $voucherWord['word'] . '-' . $voucher['voucherNo']);
                }
            }
            $text = $this->control['name'] . "导出了内部转账";
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOut($title, $data, "内部转账.xlsx");
        }
        header("Location:" . getenv("HTTP_REFERER"));
        exit(0);
    }

    /**
     * 下载模板
     */
    public function downloadModel()
    {
        $templateId = $this->get('templateId');
        if (!$this->power(self::page, 'import')) {
            $_SESSION['warn'] = '你还没有导入的权限';
        }  else {
            $exampleData[] = ['2022-01-01', '内部转账', '001', '现金账户', '002', '银行账户', '1000', '样例数据'];
            $excel    = $this->excelHead();
            $fileName = self::title.'导入模板-'.importTemplateClass::getName($templateId).'.xlsx';
            $filePath = $excel->fileName($fileName, 'sheet1');
            $format = new \Vtiful\Kernel\Format($filePath->getHandle());
            $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
            $index         = 0;
            foreach ($templateField as $k => $array) {
                if ($array['display']){
                    $backgroundStyle=null;
                    if (importTemplateClass::getIsMustValue($this->importFieldInit(), $array['columnName'])){
                        //必填项判断
                        $backgroundStyle  = $format->background(
                            0xFFC04B
                        )->toResource();
                    }
                    $filePath->insertText(0, $index, $array['aliasName'],'',$backgroundStyle);
                    foreach ($exampleData as $y=>$example){
                        $exampleVal = match ($array['columnName']){
                            '日期'=>$example[0],
                            '摘要'=>$example[1],
                            '转出账户编号'=>$example[2],
                            '转出账户名称'=>$example[3],
                            '转入账户编号'=>$example[4],
                            '转入账户名称'=>$example[5],
                            '金额'=>$example[6],
                            '备注'=>$example[7],
                            default=>'',
                        };
                        $filePath->insertText($y+1, $index, $exampleVal);
                    }
                    $index++;
                }
            }
            $text   = $this->control['name'] . "下载了内部转账导入模板";
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOutPut($filePath,$fileName);
            exit(0);
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }

    /*数据导入分析*/
    public function importData()
    {
        $templateId = $this->post('templateId');
        if (!$this->power(self::page, 'import')) {
            $json['warn'] = '你还没有导入的权限';
        }  else {
             $fomatArray = [];//导入数据格式同一为TYPE_STRING
            foreach ($this->importFieldInit() as $value){
                $fomatArray[] = \Vtiful\Kernel\Excel::TYPE_STRING;
            }
            $data = $this->importHead(format: $fomatArray);
            $x    = 0;
            $text = '';
            $headArray = [];
            $row_list=0;
            foreach ($data as $i => $row) {
                $row_list++;
                if ($i==0){
                    $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
                    $headArray = importTemplateClass::combinHead($templateField,$row);
                }
                if ($i > 0) {
                    $rowData = formSubArray($row);
                    //只接收模板中选中的字段的值
                    $cell = [];
                    foreach ($headArray as $index=>$headName){
                        $cell[$headName] = $rowData[$index]??'';
                    }
                    //初始化未被模板需要的字段的值
                    foreach ($this->importFieldInit() as $value){
                        $cell[$value['columnName']] = $cell[$value['columnName']]??'';
                    }
                    $inAccount  = query('account', "orderNo = '$cell[转入账户编号]' and coid = '" . self::$coid . "'");
                    $outAccount = query('account', "orderNo = '$cell[转出账户编号]' and coid = '" . self::$coid . "'");
                    $field      = [
                        'id'           => suiji(),
                        'coid'         => self::$coid,
                        'stid'         => self::$stid,
                        'inAccountId'  => $inAccount['id'],
                        'outAccountId' => $outAccount['id'],
                        'recordDate'   => self::importDateFormat($cell['日期']),
                        'summary'      => $cell['摘要'],
                        'money'        => $cell['金额'],
                        'text'         => $cell['备注'],
                    ];
                    $annotation = [
                        'outAccountId' => '转出账户',
                        'inAccountId'  => '转入账户',
                        'recordDate'   => '日期',
                        'money'        => '金额',
                        'summary'      => '摘要',
                    ];
                    $rules      = [
                        'outAccountId' => 'required',
                        'inAccountId'  => 'required',
                        'recordDate'   => 'required|date',
                        'money'        => 'required|numeric',
                        'summary'      => 'required',
                    ];
                    // 校验是否符合规则
                    $vt     = new \verify();
                    $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
                    if ($result === false) {
                        $text .= "第【{$row_list}】行：" . $vt->getErrs()[0] . "<br>";  // 多个规则提示最前面一条
                    } else {

                        $warn = insert(["table" => self::table, "field" => $field]);
                        if (in_array($warn, ["新增成功", "更新成功"])) {
                            //添加日记账
                            if ($inAccount['type'] == '现金') {
                                $userNo = codeTemplateClass::generateCode('cashBook', [
                                    'prefix' => date('Ymd'),
                                    'table'  => 'bookkeeping',
                                    'field'  => 'orderNo',
                                    'where'  => '',
                                ], []);
                            } else {
                                $userNo = codeTemplateClass::generateCode('bankBook', [
                                    'prefix' => date('Ymd'),
                                    'table'  => 'bookkeeping',
                                    'field'  => 'orderNo',
                                    'where'  => '',
                                ], []);
                            }
                            static::insert(["table" => 'bookkeeping', "field" => [
                                'id'          => suiji(),
                                'orderNo'     => $userNo,
                                'type'        => $inAccount['type'] == '现金' ? '现金' : '银行账户',
                                'coid'        => self::$coid,
                                'stid'        => self::$stid,
                                'accountId'   => $field['inAccountId'],
                                'classify'    => '内部转账',
                                'recordDate'  => $field['recordDate'],
                                'summary'     => $field['summary'],
                                'income'      => $field['money'],
                                'sourceTable' => self::table,
                                'sourceId'    => $field['id'],
                                'sign'        => '转入账户'
                            ]]);
                            //添加日记账
                            if ($outAccount['type'] == '现金') {
                                $userNo = codeTemplateClass::generateCode('cashBook', [
                                    'prefix' => date('Ymd'),
                                    'table'  => 'bookkeeping',
                                    'field'  => 'orderNo',
                                    'where'  => '',
                                ], []);
                            } else {
                                $userNo = codeTemplateClass::generateCode('bankBook', [
                                    'prefix' => date('Ymd'),
                                    'table'  => 'bookkeeping',
                                    'field'  => 'orderNo',
                                    'where'  => '',
                                ], []);
                            }
                            static::insert(["table" => 'bookkeeping', "field" => [
                                'id'          => suiji(),
                                'orderNo'     => $userNo,
                                'type'        => $outAccount['type'] == '现金' ? '现金' : '银行账户',
                                'coid'        => self::$coid,
                                'stid'        => self::$stid,
                                'accountId'   => $field['outAccountId'],
                                'classify'    => '内部转账',
                                'recordDate'  => $field['recordDate'],
                                'summary'     => $field['summary'],
                                'expenses'    => $field['money'],
                                'sourceTable' => self::table,
                                'sourceId'    => $field['id'],
                                'sign'        => '转出账户'
                            ]]);
                            $x++;
                            $text .= "第【{$row_list}】行：导入成功<br>";
                        } else {
                            $text .= "第【{$row_list}】行：导入失败：编辑失败<br>";
                        }
                    }
                }
            }
            $total = count($data)-1;
            $json['data'] = [
                'text'=>$text,
                'title'=>"您导入了{$total}条数据，成功{$x}条，失败".($total-$x)."条",
            ];
            $text = $this->control['name'] . '导入了文件：' . $_FILES['file']['name'] . '：' . $text;
            $this->logText(["type" => self::page, "text" => $text]);
            $json['warn'] = 2;
        }
        return json_encode($json,320);
    }


    // 操作中转
    public function operate()
    {
        $act  = $this->post('act') ?? '';
        $pwd  = false; // 需要密码
        $form = $power = $word = '';
        switch ($act) {
            default:
                $act      = 'del';
                $msg      = '删除' . self::title;
                $title    = self::page . 'Delete';
                $function = 'delete';
                $form     = self::page . 'OperateForm, listForm';
                $power    = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = '你还没有' . $msg . '的权限';
            $json             = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title'    => $title,
                'function' => $function,
                'form'     => $form,
                'power'    => $power,
                'pwd'      => $pwd,
                'word'     => $word,
            ]);
        }

        resp:
        return json_encode($json, 320);
    }


    /**
     * 删除
     * @return bool|string
     */
    public function delete()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = "你没有删除的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
//                if ($info['state'] != '草稿') {
//                    $warn = "不是草稿状态，暂不能删除";
//                } else {
                //最后删除基本参数
                delete(array("table" => self::table, "where" => " id = '$id' "));
                //删除流水
                delete(array("table" => 'account_report', "where" => " sourceId = '$id' "));
                delete(array("table" => 'bookkeeping', "where" => " sourceId = '$id' "));
                //返回
                $warn = "删除成功";
                $x++;
//                }
                $text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }

    /**
     * 导入模板字段初始化
     * @return array[]
     */
    public function importFieldInit($classify=''): array
    {
        return match ($classify) {
            default=>  [
                [
                    'columnName'=>'日期',
                    'aliasName'=>'日期',
                    'isMust'=>true,
                ],
                [
                    'columnName'=>'摘要',
                    'aliasName'=>'摘要',
                    'isMust'=>true,
                ],
                [
                    'columnName'=>'转出账户编号',
                    'aliasName'=>'转出账户编号',
                    'isMust'=>true,
                ],
                [
                    'columnName'=>'转出账户名称',
                    'aliasName'=>'转出账户名称',
                    'isMust'=>false,
                ],
                [
                    'columnName'=>'转入账户编号',
                    'aliasName'=>'转入账户编号',
                    'isMust'=>true,
                ],
                [
                    'columnName'=>'转入账户名称',
                    'aliasName'=>'转入账户名称',
                    'isMust'=>false,
                ],
                [
                    'columnName'=>'金额',
                    'aliasName'=>'金额',
                    'isMust'=>true,
                ],
                [
                    'columnName'=>'备注',
                    'aliasName'=>'备注',
                    'isMust'=>false,
                ],
            ]
        };
    }

}

